<?xml version='1.0' encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html lang="en" xml:lang="en" xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <link href="cpip.css" rel="stylesheet" type="text/css" />
    <title>File: /Users/paulross/dev/Python-3.6.2/Include/pyatomic.h</title>
  </head>
  <body>
    <h1>File: /Users/paulross/dev/Python-3.6.2/Include/pyatomic.h</h1>
    <p>Green shading in the line number column
means the source is part of the translation unit, red means it is conditionally excluded.
Highlighted line numbers link to the translation unit page. Highlighted macros link to
the macro page.</p>
    <pre><a name="1" /><span class="True">       1:</span> <span class="f">#</span><span class="n">ifndef</span> <a href="macros_noref.html#_UHlfQVRPTUlDX0hfMA__"><span class="b">Py_ATOMIC_H</span></a>
<a name="2" /><span class="True">       2:</span> <span class="f">#</span><span class="n">define</span> <a href="macros_noref.html#_UHlfQVRPTUlDX0hfMA__"><span class="b">Py_ATOMIC_H</span></a>
<a name="3" /><span class="False">       3:</span> <span class="f">#</span><span class="n">ifdef</span> <span class="b">Py_BUILD_CORE</span>
<a name="4" /><span class="False">       4:</span> 
<a name="5" /><span class="False">       5:</span> <span class="f">#</span><span class="n">include</span> <span class="e">&quot;dynamic_annotations.h&quot;</span>
<a name="6" /><span class="False">       6:</span> 
<a name="7" /><span class="False">       7:</span> <span class="f">#</span><span class="n">include</span> <span class="e">&quot;pyconfig.h&quot;</span>
<a name="8" /><span class="False">       8:</span> 
<a name="9" /><span class="False">       9:</span> <span class="f">#</span><span class="n">if</span> <span class="b">defined</span><span class="f">(</span><span class="b">HAVE_STD_ATOMIC</span><span class="f">)</span>
<a name="10" /><span class="False">      10:</span> <span class="f">#</span><span class="n">include</span> <span class="f">&lt;</span><span class="b">stdatomic</span><span class="f">.</span><span class="b">h</span><span class="f">&gt;</span>
<a name="11" /><span class="False">      11:</span> <span class="f">#</span><span class="n">endif</span>
<a name="12" /><span class="False">      12:</span> 
<a name="13" /><span class="False">      13:</span> <span class="k">/* This is modeled after the atomics interface from C1x, according to</span>
<a name="14" /><span class="False">      14:</span> <span class="k"> * the draft at</span>
<a name="15" /><span class="False">      15:</span> <span class="k"> * http://www.open-std.org/JTC1/SC22/wg14/www/docs/n1425.pdf.</span>
<a name="16" /><span class="False">      16:</span> <span class="k"> * Operations and types are named the same except with a _Py_ prefix</span>
<a name="17" /><span class="False">      17:</span> <span class="k"> * and have the same semantics.</span>
<a name="18" /><span class="False">      18:</span> <span class="k"> *</span>
<a name="19" /><span class="False">      19:</span> <span class="k"> * Beware, the implementations here are deep magic.</span>
<a name="20" /><span class="False">      20:</span> <span class="k"> */</span>
<a name="21" /><span class="False">      21:</span> 
<a name="22" /><span class="False">      22:</span> <span class="f">#</span><span class="n">if</span> <span class="b">defined</span><span class="f">(</span><span class="b">HAVE_STD_ATOMIC</span><span class="f">)</span>
<a name="23" /><span class="False">      23:</span> 
<a name="24" /><span class="False">      24:</span> <span class="m">typedef</span> <span class="m">enum</span> <span class="b">_Py_memory_order</span> <span class="f">{</span>
<a name="25" /><span class="False">      25:</span>     <span class="b">_Py_memory_order_relaxed</span> <span class="f">=</span> <span class="b">memory_order_relaxed</span><span class="f">,</span>
<a name="26" /><span class="False">      26:</span>     <span class="b">_Py_memory_order_acquire</span> <span class="f">=</span> <span class="b">memory_order_acquire</span><span class="f">,</span>
<a name="27" /><span class="False">      27:</span>     <span class="b">_Py_memory_order_release</span> <span class="f">=</span> <span class="b">memory_order_release</span><span class="f">,</span>
<a name="28" /><span class="False">      28:</span>     <span class="b">_Py_memory_order_acq_rel</span> <span class="f">=</span> <span class="b">memory_order_acq_rel</span><span class="f">,</span>
<a name="29" /><span class="False">      29:</span>     <span class="b">_Py_memory_order_seq_cst</span> <span class="f">=</span> <span class="b">memory_order_seq_cst</span>
<a name="30" /><span class="False">      30:</span> <span class="f">}</span> <span class="b">_Py_memory_order</span><span class="f">;</span>
<a name="31" /><span class="False">      31:</span> 
<a name="32" /><span class="False">      32:</span> <span class="m">typedef</span> <span class="m">struct</span> <span class="b">_Py_atomic_address</span> <span class="f">{</span>
<a name="33" /><span class="False">      33:</span>     <span class="b">atomic_uintptr_t</span> <span class="b">_value</span><span class="f">;</span>
<a name="34" /><span class="False">      34:</span> <span class="f">}</span> <span class="b">_Py_atomic_address</span><span class="f">;</span>
<a name="35" /><span class="False">      35:</span> 
<a name="36" /><span class="False">      36:</span> <span class="m">typedef</span> <span class="m">struct</span> <span class="b">_Py_atomic_int</span> <span class="f">{</span>
<a name="37" /><span class="False">      37:</span>     <span class="b">atomic_int</span> <span class="b">_value</span><span class="f">;</span>
<a name="38" /><span class="False">      38:</span> <span class="f">}</span> <span class="b">_Py_atomic_int</span><span class="f">;</span>
<a name="39" /><span class="False">      39:</span> 
<a name="40" /><span class="False">      40:</span> <span class="f">#</span><span class="n">define</span> <span class="b">_Py_atomic_signal_fence</span><span class="f">(</span><span class="k">/*memory_order*/</span> <span class="b">ORDER</span><span class="f">)</span> \
<a name="41" /><span class="False">      41:</span>     <span class="b">atomic_signal_fence</span><span class="f">(</span><span class="b">ORDER</span><span class="f">)</span>
<a name="42" /><span class="False">      42:</span> 
<a name="43" /><span class="False">      43:</span> <span class="f">#</span><span class="n">define</span> <span class="b">_Py_atomic_thread_fence</span><span class="f">(</span><span class="k">/*memory_order*/</span> <span class="b">ORDER</span><span class="f">)</span> \
<a name="44" /><span class="False">      44:</span>     <span class="b">atomic_thread_fence</span><span class="f">(</span><span class="b">ORDER</span><span class="f">)</span>
<a name="45" /><span class="False">      45:</span> 
<a name="46" /><span class="False">      46:</span> <span class="f">#</span><span class="n">define</span> <span class="b">_Py_atomic_store_explicit</span><span class="f">(</span><span class="b">ATOMIC_VAL</span><span class="f">,</span> <span class="b">NEW_VAL</span><span class="f">,</span> <span class="b">ORDER</span><span class="f">)</span> \
<a name="47" /><span class="False">      47:</span>     <span class="b">atomic_store_explicit</span><span class="f">(</span><span class="f">&amp;</span><span class="f">(</span><span class="b">ATOMIC_VAL</span><span class="f">)</span><span class="f">-&gt;</span><span class="b">_value</span><span class="f">,</span> <span class="b">NEW_VAL</span><span class="f">,</span> <span class="b">ORDER</span><span class="f">)</span>
<a name="48" /><span class="False">      48:</span> 
<a name="49" /><span class="False">      49:</span> <span class="f">#</span><span class="n">define</span> <span class="b">_Py_atomic_load_explicit</span><span class="f">(</span><span class="b">ATOMIC_VAL</span><span class="f">,</span> <span class="b">ORDER</span><span class="f">)</span> \
<a name="50" /><span class="False">      50:</span>     <span class="b">atomic_load_explicit</span><span class="f">(</span><span class="f">&amp;</span><span class="f">(</span><span class="b">ATOMIC_VAL</span><span class="f">)</span><span class="f">-&gt;</span><span class="b">_value</span><span class="f">,</span> <span class="b">ORDER</span><span class="f">)</span>
<a name="51" /><span class="False">      51:</span> 
<a name="52" /><span class="False">      52:</span> <span class="k">/* Use builtin atomic operations in GCC &gt;= 4.7 */</span>
<a name="53" /><span class="False">      53:</span> <span class="f">#</span><span class="n">elif</span> <span class="b">defined</span><span class="f">(</span><a href="macros_ref.html#_SEFWRV9CVUlMVElOX0FUT01JQ18w"><span class="b">HAVE_BUILTIN_ATOMIC</span></a><span class="f">)</span>
<a name="54" /><span class="False">      54:</span> 
<a name="55" /><span class="False">      55:</span> <span class="m">typedef</span> <span class="m">enum</span> <span class="b">_Py_memory_order</span> <span class="f">{</span>
<a name="56" /><span class="False">      56:</span>     <span class="b">_Py_memory_order_relaxed</span> <span class="f">=</span> <span class="b">__ATOMIC_RELAXED</span><span class="f">,</span>
<a name="57" /><span class="False">      57:</span>     <span class="b">_Py_memory_order_acquire</span> <span class="f">=</span> <span class="b">__ATOMIC_ACQUIRE</span><span class="f">,</span>
<a name="58" /><span class="False">      58:</span>     <span class="b">_Py_memory_order_release</span> <span class="f">=</span> <span class="b">__ATOMIC_RELEASE</span><span class="f">,</span>
<a name="59" /><span class="False">      59:</span>     <span class="b">_Py_memory_order_acq_rel</span> <span class="f">=</span> <span class="b">__ATOMIC_ACQ_REL</span><span class="f">,</span>
<a name="60" /><span class="False">      60:</span>     <span class="b">_Py_memory_order_seq_cst</span> <span class="f">=</span> <span class="b">__ATOMIC_SEQ_CST</span>
<a name="61" /><span class="False">      61:</span> <span class="f">}</span> <span class="b">_Py_memory_order</span><span class="f">;</span>
<a name="62" /><span class="False">      62:</span> 
<a name="63" /><span class="False">      63:</span> <span class="m">typedef</span> <span class="m">struct</span> <span class="b">_Py_atomic_address</span> <span class="f">{</span>
<a name="64" /><span class="False">      64:</span>     <span class="b">uintptr_t</span> <span class="b">_value</span><span class="f">;</span>
<a name="65" /><span class="False">      65:</span> <span class="f">}</span> <span class="b">_Py_atomic_address</span><span class="f">;</span>
<a name="66" /><span class="False">      66:</span> 
<a name="67" /><span class="False">      67:</span> <span class="m">typedef</span> <span class="m">struct</span> <span class="b">_Py_atomic_int</span> <span class="f">{</span>
<a name="68" /><span class="False">      68:</span>     <span class="m">int</span> <span class="b">_value</span><span class="f">;</span>
<a name="69" /><span class="False">      69:</span> <span class="f">}</span> <span class="b">_Py_atomic_int</span><span class="f">;</span>
<a name="70" /><span class="False">      70:</span> 
<a name="71" /><span class="False">      71:</span> <span class="f">#</span><span class="n">define</span> <span class="b">_Py_atomic_signal_fence</span><span class="f">(</span><span class="k">/*memory_order*/</span> <span class="b">ORDER</span><span class="f">)</span> \
<a name="72" /><span class="False">      72:</span>     <span class="b">__atomic_signal_fence</span><span class="f">(</span><span class="b">ORDER</span><span class="f">)</span>
<a name="73" /><span class="False">      73:</span> 
<a name="74" /><span class="False">      74:</span> <span class="f">#</span><span class="n">define</span> <span class="b">_Py_atomic_thread_fence</span><span class="f">(</span><span class="k">/*memory_order*/</span> <span class="b">ORDER</span><span class="f">)</span> \
<a name="75" /><span class="False">      75:</span>     <span class="b">__atomic_thread_fence</span><span class="f">(</span><span class="b">ORDER</span><span class="f">)</span>
<a name="76" /><span class="False">      76:</span> 
<a name="77" /><span class="False">      77:</span> <span class="f">#</span><span class="n">define</span> <span class="b">_Py_atomic_store_explicit</span><span class="f">(</span><span class="b">ATOMIC_VAL</span><span class="f">,</span> <span class="b">NEW_VAL</span><span class="f">,</span> <span class="b">ORDER</span><span class="f">)</span> \
<a name="78" /><span class="False">      78:</span>     <span class="f">(</span><a href="macros_ref.html#_YXNzZXJ0XzA_"><span class="b">assert</span></a><span class="f">(</span><span class="f">(</span><span class="b">ORDER</span><span class="f">)</span> <span class="f">==</span> <span class="b">__ATOMIC_RELAXED</span>                       \
<a name="79" /><span class="False">      79:</span>             <span class="f">||</span> <span class="f">(</span><span class="b">ORDER</span><span class="f">)</span> <span class="f">==</span> <span class="b">__ATOMIC_SEQ_CST</span>                    \
<a name="80" /><span class="False">      80:</span>             <span class="f">||</span> <span class="f">(</span><span class="b">ORDER</span><span class="f">)</span> <span class="f">==</span> <span class="b">__ATOMIC_RELEASE</span><span class="f">)</span><span class="f">,</span>                  \
<a name="81" /><span class="False">      81:</span>      <span class="b">__atomic_store_n</span><span class="f">(</span><span class="f">&amp;</span><span class="f">(</span><span class="b">ATOMIC_VAL</span><span class="f">)</span><span class="f">-&gt;</span><span class="b">_value</span><span class="f">,</span> <span class="b">NEW_VAL</span><span class="f">,</span> <span class="b">ORDER</span><span class="f">)</span><span class="f">)</span>
<a name="82" /><span class="False">      82:</span> 
<a name="83" /><span class="False">      83:</span> <span class="f">#</span><span class="n">define</span> <span class="b">_Py_atomic_load_explicit</span><span class="f">(</span><span class="b">ATOMIC_VAL</span><span class="f">,</span> <span class="b">ORDER</span><span class="f">)</span>           \
<a name="84" /><span class="False">      84:</span>     <span class="f">(</span><a href="macros_ref.html#_YXNzZXJ0XzA_"><span class="b">assert</span></a><span class="f">(</span><span class="f">(</span><span class="b">ORDER</span><span class="f">)</span> <span class="f">==</span> <span class="b">__ATOMIC_RELAXED</span>                       \
<a name="85" /><span class="False">      85:</span>             <span class="f">||</span> <span class="f">(</span><span class="b">ORDER</span><span class="f">)</span> <span class="f">==</span> <span class="b">__ATOMIC_SEQ_CST</span>                    \
<a name="86" /><span class="False">      86:</span>             <span class="f">||</span> <span class="f">(</span><span class="b">ORDER</span><span class="f">)</span> <span class="f">==</span> <span class="b">__ATOMIC_ACQUIRE</span>                    \
<a name="87" /><span class="False">      87:</span>             <span class="f">||</span> <span class="f">(</span><span class="b">ORDER</span><span class="f">)</span> <span class="f">==</span> <span class="b">__ATOMIC_CONSUME</span><span class="f">)</span><span class="f">,</span>                  \
<a name="88" /><span class="False">      88:</span>      <span class="b">__atomic_load_n</span><span class="f">(</span><span class="f">&amp;</span><span class="f">(</span><span class="b">ATOMIC_VAL</span><span class="f">)</span><span class="f">-&gt;</span><span class="b">_value</span><span class="f">,</span> <span class="b">ORDER</span><span class="f">)</span><span class="f">)</span>
<a name="89" /><span class="False">      89:</span> 
<a name="90" /><span class="False">      90:</span> <span class="f">#</span><span class="n">else</span>
<a name="91" /><span class="False">      91:</span> 
<a name="92" /><span class="False">      92:</span> <span class="m">typedef</span> <span class="m">enum</span> <span class="b">_Py_memory_order</span> <span class="f">{</span>
<a name="93" /><span class="False">      93:</span>     <span class="b">_Py_memory_order_relaxed</span><span class="f">,</span>
<a name="94" /><span class="False">      94:</span>     <span class="b">_Py_memory_order_acquire</span><span class="f">,</span>
<a name="95" /><span class="False">      95:</span>     <span class="b">_Py_memory_order_release</span><span class="f">,</span>
<a name="96" /><span class="False">      96:</span>     <span class="b">_Py_memory_order_acq_rel</span><span class="f">,</span>
<a name="97" /><span class="False">      97:</span>     <span class="b">_Py_memory_order_seq_cst</span>
<a name="98" /><span class="False">      98:</span> <span class="f">}</span> <span class="b">_Py_memory_order</span><span class="f">;</span>
<a name="99" /><span class="False">      99:</span> 
<a name="100" /><span class="False">     100:</span> <span class="m">typedef</span> <span class="m">struct</span> <span class="b">_Py_atomic_address</span> <span class="f">{</span>
<a name="101" /><span class="False">     101:</span>     <span class="b">uintptr_t</span> <span class="b">_value</span><span class="f">;</span>
<a name="102" /><span class="False">     102:</span> <span class="f">}</span> <span class="b">_Py_atomic_address</span><span class="f">;</span>
<a name="103" /><span class="False">     103:</span> 
<a name="104" /><span class="False">     104:</span> <span class="m">typedef</span> <span class="m">struct</span> <span class="b">_Py_atomic_int</span> <span class="f">{</span>
<a name="105" /><span class="False">     105:</span>     <span class="m">int</span> <span class="b">_value</span><span class="f">;</span>
<a name="106" /><span class="False">     106:</span> <span class="f">}</span> <span class="b">_Py_atomic_int</span><span class="f">;</span>
<a name="107" /><span class="False">     107:</span> 
<a name="108" /><span class="False">     108:</span> <span class="k">/* Only support GCC (for expression statements) and x86 (for simple</span>
<a name="109" /><span class="False">     109:</span> <span class="k"> * atomic semantics) for now */</span>
<a name="110" /><span class="False">     110:</span> <span class="f">#</span><span class="n">if</span> <span class="b">defined</span><span class="f">(</span><a href="macros_ref.html#_X19HTlVDX19fMA__"><span class="b">__GNUC__</span></a><span class="f">)</span> <span class="f">&amp;&amp;</span> <span class="f">(</span><span class="b">defined</span><span class="f">(</span><span class="b">__i386__</span><span class="f">)</span> <span class="f">||</span> <span class="b">defined</span><span class="f">(</span><span class="b">__amd64</span><span class="f">)</span><span class="f">)</span>
<a name="111" /><span class="False">     111:</span> 
<a name="112" /><span class="False">     112:</span> <span class="m">static</span> <span class="b">__inline__</span> <span class="m">void</span>
<a name="113" /><span class="False">     113:</span> <span class="b">_Py_atomic_signal_fence</span><span class="f">(</span><span class="b">_Py_memory_order</span> <span class="b">order</span><span class="f">)</span>
<a name="114" /><span class="False">     114:</span> <span class="f">{</span>
<a name="115" /><span class="False">     115:</span>     <span class="m">if</span> <span class="f">(</span><span class="b">order</span> <span class="f">!=</span> <span class="b">_Py_memory_order_relaxed</span><span class="f">)</span>
<a name="116" /><span class="False">     116:</span>         <span class="b">__asm__</span> <span class="m">volatile</span><span class="f">(</span><span class="e">&quot;&quot;</span><span class="f">::</span><span class="f">:</span><span class="e">&quot;memory&quot;</span><span class="f">)</span><span class="f">;</span>
<a name="117" /><span class="False">     117:</span> <span class="f">}</span>
<a name="118" /><span class="False">     118:</span> 
<a name="119" /><span class="False">     119:</span> <span class="m">static</span> <span class="b">__inline__</span> <span class="m">void</span>
<a name="120" /><span class="False">     120:</span> <span class="b">_Py_atomic_thread_fence</span><span class="f">(</span><span class="b">_Py_memory_order</span> <span class="b">order</span><span class="f">)</span>
<a name="121" /><span class="False">     121:</span> <span class="f">{</span>
<a name="122" /><span class="False">     122:</span>     <span class="m">if</span> <span class="f">(</span><span class="b">order</span> <span class="f">!=</span> <span class="b">_Py_memory_order_relaxed</span><span class="f">)</span>
<a name="123" /><span class="False">     123:</span>         <span class="b">__asm__</span> <span class="m">volatile</span><span class="f">(</span><span class="e">&quot;mfence&quot;</span><span class="f">::</span><span class="f">:</span><span class="e">&quot;memory&quot;</span><span class="f">)</span><span class="f">;</span>
<a name="124" /><span class="False">     124:</span> <span class="f">}</span>
<a name="125" /><span class="False">     125:</span> 
<a name="126" /><span class="False">     126:</span> <span class="k">/* Tell the race checker about this operation&apos;s effects. */</span>
<a name="127" /><span class="False">     127:</span> <span class="m">static</span> <span class="b">__inline__</span> <span class="m">void</span>
<a name="128" /><span class="False">     128:</span> <span class="b">_Py_ANNOTATE_MEMORY_ORDER</span><span class="f">(</span><span class="m">const</span> <span class="m">volatile</span> <span class="m">void</span> <span class="f">*</span><span class="b">address</span><span class="f">,</span> <span class="b">_Py_memory_order</span> <span class="b">order</span><span class="f">)</span>
<a name="129" /><span class="False">     129:</span> <span class="f">{</span>
<a name="130" /><span class="False">     130:</span>     <span class="f">(</span><span class="m">void</span><span class="f">)</span><span class="b">address</span><span class="f">;</span>        <span class="k">/* shut up -Wunused-parameter */</span>
<a name="131" /><span class="False">     131:</span>     <span class="m">switch</span><span class="f">(</span><span class="b">order</span><span class="f">)</span> <span class="f">{</span>
<a name="132" /><span class="False">     132:</span>     <span class="m">case</span> <span class="b">_Py_memory_order_release</span><span class="f">:</span>
<a name="133" /><span class="False">     133:</span>     <span class="m">case</span> <span class="b">_Py_memory_order_acq_rel</span><span class="f">:</span>
<a name="134" /><span class="False">     134:</span>     <span class="m">case</span> <span class="b">_Py_memory_order_seq_cst</span><span class="f">:</span>
<a name="135" /><span class="False">     135:</span>         <span class="b">_Py_ANNOTATE_HAPPENS_BEFORE</span><span class="f">(</span><span class="b">address</span><span class="f">)</span><span class="f">;</span>
<a name="136" /><span class="False">     136:</span>         <span class="m">break</span><span class="f">;</span>
<a name="137" /><span class="False">     137:</span>     <span class="m">case</span> <span class="b">_Py_memory_order_relaxed</span><span class="f">:</span>
<a name="138" /><span class="False">     138:</span>     <span class="m">case</span> <span class="b">_Py_memory_order_acquire</span><span class="f">:</span>
<a name="139" /><span class="False">     139:</span>         <span class="m">break</span><span class="f">;</span>
<a name="140" /><span class="False">     140:</span>     <span class="f">}</span>
<a name="141" /><span class="False">     141:</span>     <span class="m">switch</span><span class="f">(</span><span class="b">order</span><span class="f">)</span> <span class="f">{</span>
<a name="142" /><span class="False">     142:</span>     <span class="m">case</span> <span class="b">_Py_memory_order_acquire</span><span class="f">:</span>
<a name="143" /><span class="False">     143:</span>     <span class="m">case</span> <span class="b">_Py_memory_order_acq_rel</span><span class="f">:</span>
<a name="144" /><span class="False">     144:</span>     <span class="m">case</span> <span class="b">_Py_memory_order_seq_cst</span><span class="f">:</span>
<a name="145" /><span class="False">     145:</span>         <span class="b">_Py_ANNOTATE_HAPPENS_AFTER</span><span class="f">(</span><span class="b">address</span><span class="f">)</span><span class="f">;</span>
<a name="146" /><span class="False">     146:</span>         <span class="m">break</span><span class="f">;</span>
<a name="147" /><span class="False">     147:</span>     <span class="m">case</span> <span class="b">_Py_memory_order_relaxed</span><span class="f">:</span>
<a name="148" /><span class="False">     148:</span>     <span class="m">case</span> <span class="b">_Py_memory_order_release</span><span class="f">:</span>
<a name="149" /><span class="False">     149:</span>         <span class="m">break</span><span class="f">;</span>
<a name="150" /><span class="False">     150:</span>     <span class="f">}</span>
<a name="151" /><span class="False">     151:</span> <span class="f">}</span>
<a name="152" /><span class="False">     152:</span> 
<a name="153" /><span class="False">     153:</span> <span class="f">#</span><span class="n">define</span> <span class="b">_Py_atomic_store_explicit</span><span class="f">(</span><span class="b">ATOMIC_VAL</span><span class="f">,</span> <span class="b">NEW_VAL</span><span class="f">,</span> <span class="b">ORDER</span><span class="f">)</span> \
<a name="154" /><span class="False">     154:</span>     <span class="b">__extension__</span> <span class="f">(</span><span class="f">{</span> \
<a name="155" /><span class="False">     155:</span>         <span class="b">__typeof__</span><span class="f">(</span><span class="b">ATOMIC_VAL</span><span class="f">)</span> <span class="b">atomic_val</span> <span class="f">=</span> <span class="b">ATOMIC_VAL</span><span class="f">;</span> \
<a name="156" /><span class="False">     156:</span>         <span class="b">__typeof__</span><span class="f">(</span><span class="b">atomic_val</span><span class="f">-&gt;</span><span class="b">_value</span><span class="f">)</span> <span class="b">new_val</span> <span class="f">=</span> <span class="b">NEW_VAL</span><span class="f">;\
</span>        <span class="m">volatile</span> <span class="b">__typeof__</span><span class="f">(</span><span class="b">new_val</span><span class="f">)</span> <span class="f">*</span><span class="b">volatile_data</span> <span class="f">=</span> <span class="f">&amp;</span><span class="b">atomic_val</span><span class="f">-&gt;</span><span class="b">_value</span><span class="f">;</span> \
<a name="158" /><span class="False">     158:</span>         <span class="b">_Py_memory_order</span> <span class="b">order</span> <span class="f">=</span> <span class="b">ORDER</span><span class="f">;</span> \
<a name="159" /><span class="False">     159:</span>         <span class="b">_Py_ANNOTATE_MEMORY_ORDER</span><span class="f">(</span><span class="b">atomic_val</span><span class="f">,</span> <span class="b">order</span><span class="f">)</span><span class="f">;</span> \
<a name="160" /><span class="False">     160:</span>         \
<a name="161" /><span class="False">     161:</span>         <span class="k">/* Perform the operation. */</span> \
<a name="162" /><span class="False">     162:</span>         <span class="b">_Py_ANNOTATE_IGNORE_WRITES_BEGIN</span><span class="f">(</span><span class="f">)</span><span class="f">;</span> \
<a name="163" /><span class="False">     163:</span>         <span class="m">switch</span><span class="f">(</span><span class="b">order</span><span class="f">)</span> <span class="f">{</span> \
<a name="164" /><span class="False">     164:</span>         <span class="m">case</span> <span class="b">_Py_memory_order_release</span><span class="f">:</span> \
<a name="165" /><span class="False">     165:</span>             <span class="b">_Py_atomic_signal_fence</span><span class="f">(</span><span class="b">_Py_memory_order_release</span><span class="f">)</span><span class="f">;</span> \
<a name="166" /><span class="False">     166:</span>             <span class="k">/* fallthrough */</span> \
<a name="167" /><span class="False">     167:</span>         <span class="m">case</span> <span class="b">_Py_memory_order_relaxed</span><span class="f">:</span> \
<a name="168" /><span class="False">     168:</span>             <span class="f">*</span><span class="b">volatile_data</span> <span class="f">=</span> <span class="b">new_val</span><span class="f">;</span> \
<a name="169" /><span class="False">     169:</span>             <span class="m">break</span><span class="f">;</span> \
<a name="170" /><span class="False">     170:</span>         \
<a name="171" /><span class="False">     171:</span>         <span class="m">case</span> <span class="b">_Py_memory_order_acquire</span><span class="f">:</span> \
<a name="172" /><span class="False">     172:</span>         <span class="m">case</span> <span class="b">_Py_memory_order_acq_rel</span><span class="f">:</span> \
<a name="173" /><span class="False">     173:</span>         <span class="m">case</span> <span class="b">_Py_memory_order_seq_cst</span><span class="f">:</span> \
<a name="174" /><span class="False">     174:</span>             <span class="b">__asm__</span> <span class="m">volatile</span><span class="f">(</span><span class="e">&quot;xchg %0, %1&quot;</span> \
<a name="175" /><span class="False">     175:</span>                          <span class="f">:</span> <span class="e">&quot;+r&quot;</span><span class="f">(</span><span class="b">new_val</span><span class="f">)</span> \
<a name="176" /><span class="False">     176:</span>                          <span class="f">:</span> <span class="e">&quot;m&quot;</span><span class="f">(</span><span class="b">atomic_val</span><span class="f">-&gt;</span><span class="b">_value</span><span class="f">)</span> \
<a name="177" /><span class="False">     177:</span>                          <span class="f">:</span> <span class="e">&quot;memory&quot;</span><span class="f">)</span><span class="f">;</span> \
<a name="178" /><span class="False">     178:</span>             <span class="m">break</span><span class="f">;</span> \
<a name="179" /><span class="False">     179:</span>         <span class="f">}</span> \
<a name="180" /><span class="False">     180:</span>         <span class="b">_Py_ANNOTATE_IGNORE_WRITES_END</span><span class="f">(</span><span class="f">)</span><span class="f">;</span> \
<a name="181" /><span class="False">     181:</span>     <span class="f">}</span><span class="f">)</span>
<a name="182" /><span class="False">     182:</span> 
<a name="183" /><span class="False">     183:</span> <span class="f">#</span><span class="n">define</span> <span class="b">_Py_atomic_load_explicit</span><span class="f">(</span><span class="b">ATOMIC_VAL</span><span class="f">,</span> <span class="b">ORDER</span><span class="f">)</span> \
<a name="184" /><span class="False">     184:</span>     <span class="b">__extension__</span> <span class="f">(</span><span class="f">{</span>  \
<a name="185" /><span class="False">     185:</span>         <span class="b">__typeof__</span><span class="f">(</span><span class="b">ATOMIC_VAL</span><span class="f">)</span> <span class="b">atomic_val</span> <span class="f">=</span> <span class="b">ATOMIC_VAL</span><span class="f">;</span> \
<a name="186" /><span class="False">     186:</span>         <span class="b">__typeof__</span><span class="f">(</span><span class="b">atomic_val</span><span class="f">-&gt;</span><span class="b">_value</span><span class="f">)</span> <span class="b">result</span><span class="f">;</span> \
<a name="187" /><span class="False">     187:</span>         <span class="m">volatile</span> <span class="b">__typeof__</span><span class="f">(</span><span class="b">result</span><span class="f">)</span> <span class="f">*</span><span class="b">volatile_data</span> <span class="f">=</span> <span class="f">&amp;</span><span class="b">atomic_val</span><span class="f">-&gt;</span><span class="b">_value</span><span class="f">;</span> \
<a name="188" /><span class="False">     188:</span>         <span class="b">_Py_memory_order</span> <span class="b">order</span> <span class="f">=</span> <span class="b">ORDER</span><span class="f">;</span> \
<a name="189" /><span class="False">     189:</span>         <span class="b">_Py_ANNOTATE_MEMORY_ORDER</span><span class="f">(</span><span class="b">atomic_val</span><span class="f">,</span> <span class="b">order</span><span class="f">)</span><span class="f">;</span> \
<a name="190" /><span class="False">     190:</span>         \
<a name="191" /><span class="False">     191:</span>         <span class="k">/* Perform the operation. */</span> \
<a name="192" /><span class="False">     192:</span>         <span class="b">_Py_ANNOTATE_IGNORE_READS_BEGIN</span><span class="f">(</span><span class="f">)</span><span class="f">;</span> \
<a name="193" /><span class="False">     193:</span>         <span class="m">switch</span><span class="f">(</span><span class="b">order</span><span class="f">)</span> <span class="f">{</span> \
<a name="194" /><span class="False">     194:</span>         <span class="m">case</span> <span class="b">_Py_memory_order_release</span><span class="f">:</span> \
<a name="195" /><span class="False">     195:</span>         <span class="m">case</span> <span class="b">_Py_memory_order_acq_rel</span><span class="f">:</span> \
<a name="196" /><span class="False">     196:</span>         <span class="m">case</span> <span class="b">_Py_memory_order_seq_cst</span><span class="f">:</span> \
<a name="197" /><span class="False">     197:</span>             <span class="k">/* Loads on x86 are not releases by default, so need a */</span> \
<a name="198" /><span class="False">     198:</span>             <span class="k">/* thread fence. */</span> \
<a name="199" /><span class="False">     199:</span>             <span class="b">_Py_atomic_thread_fence</span><span class="f">(</span><span class="b">_Py_memory_order_release</span><span class="f">)</span><span class="f">;</span> \
<a name="200" /><span class="False">     200:</span>             <span class="m">break</span><span class="f">;</span> \
<a name="201" /><span class="False">     201:</span>         <span class="m">default</span><span class="f">:</span> \
<a name="202" /><span class="False">     202:</span>             <span class="k">/* No fence */</span> \
<a name="203" /><span class="False">     203:</span>             <span class="m">break</span><span class="f">;</span> \
<a name="204" /><span class="False">     204:</span>         <span class="f">}</span> \
<a name="205" /><span class="False">     205:</span>         <span class="b">result</span> <span class="f">=</span> <span class="f">*</span><span class="b">volatile_data</span><span class="f">;</span> \
<a name="206" /><span class="False">     206:</span>         <span class="m">switch</span><span class="f">(</span><span class="b">order</span><span class="f">)</span> <span class="f">{</span> \
<a name="207" /><span class="False">     207:</span>         <span class="m">case</span> <span class="b">_Py_memory_order_acquire</span><span class="f">:</span> \
<a name="208" /><span class="False">     208:</span>         <span class="m">case</span> <span class="b">_Py_memory_order_acq_rel</span><span class="f">:</span> \
<a name="209" /><span class="False">     209:</span>         <span class="m">case</span> <span class="b">_Py_memory_order_seq_cst</span><span class="f">:</span> \
<a name="210" /><span class="False">     210:</span>             <span class="k">/* Loads on x86 are automatically acquire operations so */</span> \
<a name="211" /><span class="False">     211:</span>             <span class="k">/* can get by with just a compiler fence. */</span> \
<a name="212" /><span class="False">     212:</span>             <span class="b">_Py_atomic_signal_fence</span><span class="f">(</span><span class="b">_Py_memory_order_acquire</span><span class="f">)</span><span class="f">;</span> \
<a name="213" /><span class="False">     213:</span>             <span class="m">break</span><span class="f">;</span> \
<a name="214" /><span class="False">     214:</span>         <span class="m">default</span><span class="f">:</span> \
<a name="215" /><span class="False">     215:</span>             <span class="k">/* No fence */</span> \
<a name="216" /><span class="False">     216:</span>             <span class="m">break</span><span class="f">;</span> \
<a name="217" /><span class="False">     217:</span>         <span class="f">}</span> \
<a name="218" /><span class="False">     218:</span>         <span class="b">_Py_ANNOTATE_IGNORE_READS_END</span><span class="f">(</span><span class="f">)</span><span class="f">;</span> \
<a name="219" /><span class="False">     219:</span>         <span class="b">result</span><span class="f">;</span> \
<a name="220" /><span class="False">     220:</span>     <span class="f">}</span><span class="f">)</span>
<a name="221" /><span class="False">     221:</span> 
<a name="222" /><span class="False">     222:</span> <span class="f">#</span><span class="n">else</span>  <span class="k">/* !gcc x86 */</span>
<a name="223" /><span class="False">     223:</span> <span class="k">/* Fall back to other compilers and processors by assuming that simple</span>
<a name="224" /><span class="False">     224:</span> <span class="k">   volatile accesses are atomic.  This is false, so people should port</span>
<a name="225" /><span class="False">     225:</span> <span class="k">   this. */</span>
<a name="226" /><span class="False">     226:</span> <span class="f">#</span><span class="n">define</span> <span class="b">_Py_atomic_signal_fence</span><span class="f">(</span><span class="k">/*memory_order*/</span> <span class="b">ORDER</span><span class="f">)</span> <span class="f">(</span><span class="f">(</span><span class="m">void</span><span class="f">)</span><span class="c">0</span><span class="f">)</span>
<a name="227" /><span class="False">     227:</span> <span class="f">#</span><span class="n">define</span> <span class="b">_Py_atomic_thread_fence</span><span class="f">(</span><span class="k">/*memory_order*/</span> <span class="b">ORDER</span><span class="f">)</span> <span class="f">(</span><span class="f">(</span><span class="m">void</span><span class="f">)</span><span class="c">0</span><span class="f">)</span>
<a name="228" /><span class="False">     228:</span> <span class="f">#</span><span class="n">define</span> <span class="b">_Py_atomic_store_explicit</span><span class="f">(</span><span class="b">ATOMIC_VAL</span><span class="f">,</span> <span class="b">NEW_VAL</span><span class="f">,</span> <span class="b">ORDER</span><span class="f">)</span> \
<a name="229" /><span class="False">     229:</span>     <span class="f">(</span><span class="f">(</span><span class="b">ATOMIC_VAL</span><span class="f">)</span><span class="f">-&gt;</span><span class="b">_value</span> <span class="f">=</span> <span class="b">NEW_VAL</span><span class="f">)</span>
<a name="230" /><span class="False">     230:</span> <span class="f">#</span><span class="n">define</span> <span class="b">_Py_atomic_load_explicit</span><span class="f">(</span><span class="b">ATOMIC_VAL</span><span class="f">,</span> <span class="b">ORDER</span><span class="f">)</span> \
<a name="231" /><span class="False">     231:</span>     <span class="f">(</span><span class="f">(</span><span class="b">ATOMIC_VAL</span><span class="f">)</span><span class="f">-&gt;</span><span class="b">_value</span><span class="f">)</span>
<a name="232" /><span class="False">     232:</span> 
<a name="233" /><span class="False">     233:</span> <span class="f">#</span><span class="n">endif</span>  <span class="k">/* !gcc x86 */</span>
<a name="234" /><span class="False">     234:</span> <span class="f">#</span><span class="n">endif</span>
<a name="235" /><span class="False">     235:</span> 
<a name="236" /><span class="False">     236:</span> <span class="k">/* Standardized shortcuts. */</span>
<a name="237" /><span class="False">     237:</span> <span class="f">#</span><span class="n">define</span> <span class="b">_Py_atomic_store</span><span class="f">(</span><span class="b">ATOMIC_VAL</span><span class="f">,</span> <span class="b">NEW_VAL</span><span class="f">)</span> \
<a name="238" /><span class="False">     238:</span>     <span class="b">_Py_atomic_store_explicit</span><span class="f">(</span><span class="b">ATOMIC_VAL</span><span class="f">,</span> <span class="b">NEW_VAL</span><span class="f">,</span> <span class="b">_Py_memory_order_seq_cst</span><span class="f">)</span>
<a name="239" /><span class="False">     239:</span> <span class="f">#</span><span class="n">define</span> <span class="b">_Py_atomic_load</span><span class="f">(</span><span class="b">ATOMIC_VAL</span><span class="f">)</span> \
<a name="240" /><span class="False">     240:</span>     <span class="b">_Py_atomic_load_explicit</span><span class="f">(</span><span class="b">ATOMIC_VAL</span><span class="f">,</span> <span class="b">_Py_memory_order_seq_cst</span><span class="f">)</span>
<a name="241" /><span class="False">     241:</span> 
<a name="242" /><span class="False">     242:</span> <span class="k">/* Python-local extensions */</span>
<a name="243" /><span class="False">     243:</span> 
<a name="244" /><span class="False">     244:</span> <span class="f">#</span><span class="n">define</span> <span class="b">_Py_atomic_store_relaxed</span><span class="f">(</span><span class="b">ATOMIC_VAL</span><span class="f">,</span> <span class="b">NEW_VAL</span><span class="f">)</span> \
<a name="245" /><span class="False">     245:</span>     <span class="b">_Py_atomic_store_explicit</span><span class="f">(</span><span class="b">ATOMIC_VAL</span><span class="f">,</span> <span class="b">NEW_VAL</span><span class="f">,</span> <span class="b">_Py_memory_order_relaxed</span><span class="f">)</span>
<a name="246" /><span class="False">     246:</span> <span class="f">#</span><span class="n">define</span> <span class="b">_Py_atomic_load_relaxed</span><span class="f">(</span><span class="b">ATOMIC_VAL</span><span class="f">)</span> \
<a name="247" /><span class="False">     247:</span>     <span class="b">_Py_atomic_load_explicit</span><span class="f">(</span><span class="b">ATOMIC_VAL</span><span class="f">,</span> <span class="b">_Py_memory_order_relaxed</span><span class="f">)</span>
<a name="248" /><span class="False">     248:</span> 
<a name="249" /><span class="True">     249:</span> <span class="f">#</span><span class="n">endif</span>  <span class="k">/* Py_BUILD_CORE */</span>
<a name="250" /><span class="True">     250:</span> <span class="f">#</span><span class="n">endif</span>  <span class="k">/* Py_ATOMIC_H */</span>
<a name="251" /><span class="True">     251:</span> </pre>
  </body>
</html>
